
#region Imported Namespaces
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
#endregion

namespace PHSRAG.Utility
{
	/// <summary>
	/// The ExceptionReport class provides support for logging a report to the following destinations:
	/// * Application event log
	/// * Disk file
	/// </summary>
	public class ExceptionReport
	{
		private const string EventLog = "Insight";
		private const string EventSource = "Insight";

		#region Public Types
		/// <summary>
		/// The ReportType enumeration avoids client from having to pulling in the EventLog namespace.
		/// </summary>
		public enum ReportType
		{
			/// <summary>Informational (typically used for debugging purposes)</summary>
			Information = EventLogEntryType.Information,

			/// <summary>Warning (event needs attention, but is not potentially fatal)</summary>
			Warning = EventLogEntryType.Warning,

			/// <summary>Error (event corresponds to a potentially fatal condition)</summary>
			Error = EventLogEntryType.Error
		}
		#endregion

		#region Class Variables
		private static EventLog	eventLog = new EventLog(EventLog);
		#endregion

		#region Public Methods
		/// <summary>
		/// Build a string representation of an exception object. The exception is recursively processed so as to get
		/// information from all inner exceptions.
		/// </summary>
		/// <param name="e">Exception to get info from</param>
		/// <param name="includeStackTrace">If true, stack trace (at each exception) is included in the string</param>
		/// <returns>Formatted string containing the full exception information</returns>
		public static string GetExceptionInfo(Exception e, bool includeStackTrace)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append(e.Message);
			if (includeStackTrace)
				sb.AppendFormat("\r\n{0}", e.StackTrace);
				
			while ((e = e.InnerException) != null)
			{
				sb.AppendFormat("\r\n{0}", e.Message);
				if (includeStackTrace)
					sb.AppendFormat("\r\n{0}", e.StackTrace);
			}

			return sb.ToString();
		}

		/// <summary>
		/// Write an entry into the application event log.
		/// </summary>
		/// <param name="source">Source name for the event</param>
		/// <param name="text">Text to be logged</param>
		/// <param name="type">Type of event</param>
		public static void WriteToEventLog(string source, string text, ReportType type)
		{
			try
			{
				eventLog.Source = EventSource;
				eventLog.WriteEntry(string.Format("Source: {0} \r\nException: {1}", source, text), (EventLogEntryType)type);
			}
			catch
			{
			}
		}

		/// <summary>
		/// Write an entry into the application event log.
		/// </summary>
		/// <param name="source">Source name for the event</param>
		/// <param name="e">Exception whose information is to be logged</param>
		/// <param name="includeStackTrace">If true, full stack trace information is included in the log</param>
		/// <param name="type">Type of event</param>
		public static void WriteToEventLog(string source, Exception e, bool includeStackTrace, ReportType type)
		{
			try
			{
				eventLog.Source = EventSource;
				eventLog.WriteEntry(string.Format("Source: {0} \r\nException: {1}", source, GetExceptionInfo(e, includeStackTrace)), (EventLogEntryType)type);
			}
			catch 
			{
			}
		}

		/// <summary>
		/// Write an entry into the the specified log file.
		/// </summary>
		/// <param name="source">Source name for the event</param>
		/// <param name="text">Text to be written to the log file</param>
		/// <param name="type">Type of event</param>
		/// <param name="fileName">Full path of the log file</param>
		public static void WriteToFile(string source, string text, ReportType type, string fileName)
		{
			try
			{
				using (StreamWriter writer = new StreamWriter(fileName, true))
				{
					writer.WriteLine(string.Format("{0}: {1}: ({2})\r\n{3}\r\n", DateTime.Now,
						ReportTypeToString(type), source, text));
				}
			}
			catch 
			{
			}
		}

		/// <summary>
		/// Write an entry into the the specified log file.
		/// </summary>
		/// <param name="source">Source name for the event</param>
		/// <param name="e">Exception whose information is to be logged</param>
		/// <param name="includeStackTrace">If true, full stack trace information is included in the log</param>
		/// <param name="type">Type of event</param>
		/// <param name="fileName">Full path of the log file</param>
		public static void WriteToFile(string source, Exception e, bool includeStackTrace, ReportType type, string fileName)
		{
			try
			{
				using (StreamWriter writer = new StreamWriter(fileName, true))
				{
					writer.WriteLine(string.Format("{0}: {1}: ({2})\r\n{3}\r\n", DateTime.Now,
						ReportTypeToString(type), source, GetExceptionInfo(e, includeStackTrace)));
				}
			}
			catch
			{
			}
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Convert the integral value of a ReportType to a string.
		/// </summary>
		/// <param name="type">Type of event</param>
		/// <returns>String equivalent of the type</returns>
		private static string ReportTypeToString(ReportType type)
		{
			switch (type)
			{
				case ReportType.Error: return "Error";
				case ReportType.Warning: return "Warning";
				default: return "Information";
			}
		}
		#endregion
	}
}

// --- EOF ---
